<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>AJ设备控制</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <link rel="Shortcut Icon" href="/favicon.ico"/>
    <!-- load css -->
    <script type="text/javascript" src="/plugins/jquery/jquery.2.1.4.min.js"></script>
    <script type="text/javascript" src="/plugins/layui2.5.6/layui.js"></script>
    <script type="text/javascript" src="/plugins/semantic/semantic.min.js"></script>
    <link rel="stylesheet" type="text/css" href="/plugins/semantic/semantic.css">
    <link rel="stylesheet" type="text/css" href="/plugins/layui2.5.6/css/layui.css" media="all">
    <link rel="stylesheet" type="text/css" href="/plugins/layui2.5.6/css/modules/layer/default/layer.css"
          media="all">
    <!--引入 element-ui 的样式-->
    <link rel="stylesheet" type="text/css" href="/plugins/element-ui/element.css">
    <link rel="stylesheet" type="text/css" href="/common/css/common.css" media="all">
    <!-- 必须先引入vue  后使用element-ui -->
    <script src="/plugins/vue/vue.js"></script>
    <!-- 引入element 的组件库-->
    <script src="/plugins/element-ui/element.js"></script>


    <style lang="scss" scoped>
        html, body {
            height: 100%;
            margin: 0px;
            padding: 0px;
        }

        .draw-box {
            position: relative;
        }

        #previewImg {
        }

        .positionListFixed {
            position: fixed;
            bottom: 0;
            left: 0;
            z-index: 9999999999999999;
            width: 200px;
            height: calc(95vh - 20px);
            margin-left: 10px;
            margin-bottom: 10px;
        }

        .positionTextarea {
            height: 100% !important;
        }

        .positionTextarea .el-textarea__inner {
            height: 100% !important;
        }

        .previewImgCls .el-form-item__content {
            margin-left: 0px !important;
        }

        .mousePositionCls {
            position: fixed;
            bottom: 0;
            right: 0;
            padding-right: 5px;
            font-size: 15px;
            font-weight: 600;
            z-index: 999999999999999;
        }

        .buttonPanel {
            display: inline-flex;
            justify-content: center;
            flex-direction: column;
            width: 200px;
            align-items: center;
            background: white;
        }

        .buttonPanel .el-button {
            width: 100%;
            margin-left: 0px !important;
            margin-bottom: 5px;
        }

        .nodeDivCommon {
            height: 80vh;
            overflow-y: auto;
            border: 1px solid #cdc4c4;
        }

        .nodeTreeClass {
            width: 38%;
        }

        .tree {
            overflow-x: scroll;
        }

        .el-tree::-webkit-scrollbar {
            width: 4px;
        }

        .el-tree::-webkit-scrollbar-thumb {
            background: transparent;
            border-radius: 4px;
        }

        .el-tree:hover::-webkit-scrollbar-thumb {
            background: hsla(0, 0%, 53%, 0.4);
        }

        .el-tree:hover::-webkit-scrollbar-track {
            background: hsla(0, 0%, 53%, 0.1);
        }

        .el-tree {
            display: inline-flex !important;
        }

        .nodePreviewClass {
            margin-left: 5px;
            width: 38%;
        }

        .nodeDetailDiv {
            margin-left: 5px;
            width: 24%;
        }

        .nodeDivCommon::-webkit-scrollbar {
            width: 4px;
        }

        .nodeDivCommon::-webkit-scrollbar-thumb {
            background: transparent;
            border-radius: 4px;
        }

        .nodeDivCommon:hover::-webkit-scrollbar-thumb {
            background: hsla(0, 0%, 53%, 0.4);
        }

        .nodeDivCommon:hover::-webkit-scrollbar-track {
            background: hsla(0, 0%, 53%, 0.1);
        }

        textarea::-webkit-scrollbar {
            width: 4px;
        }

        textarea::-webkit-scrollbar-thumb {
            background: transparent;
            border-radius: 4px;
        }

        textarea:hover::-webkit-scrollbar-thumb {
            background: hsla(0, 0%, 53%, 0.4);
        }

        textarea:hover::-webkit-scrollbar-track {
            background: hsla(0, 0%, 53%, 0.1);
        }

        .publicNoticeClass {
            width: 30vw;
        }

        .nodeDetailClass .el-dialog::-webkit-scrollbar {
            width: 4px;
        }

        .nodeDetailClass .el-dialog::-webkit-scrollbar-thumb {
            background: transparent;
            border-radius: 4px;
        }

        .nodeDetailClass .el-dialog:hover::-webkit-scrollbar-thumb {
            background: hsla(0, 0%, 53%, 0.4);
        }

        .nodeDetailClass .el-dialog:hover::-webkit-scrollbar-track {
            background: hsla(0, 0%, 53%, 0.1);
        }

        .nodeDetailRow {
            display: flex;
            align-items: center;
            width: 100%;
            padding: 0px 2px 0px 6px !important;
        }

        .labelClass {
            display: flex;
            font-size: 20px;
            font-weight: 600;
            flex: 1;
            margin: 5px 10px 5px 0;
        }

        .contentClass {
            display: flex;
            font-size: 20px;
            overflow: hidden;
            cursor: pointer;
        }

        .react-box {
            width: 10px;
            height: 10px;
            border: 2px dashed red;
            position: absolute;
            cursor: pointer;
            visibility: hidden;
        }

        .width100 {
            width: 100% !important;
        }

        .width75 {
            width: 75% !important;
        }

        .width50 {
            width: 50% !important;
        }

        .width40 {
            width: 40% !important;
        }

        .width60 {
            width: 60% !important;
        }

        .width45 {
            width: 45% !important;
        }

        .width30 {
            width: 30% !important;
        }

        .width25 {
            width: 25% !important;
        }

        .width20 {
            width: 20% !important;
        }

        .width15 {
            width: 15% !important;
        }

        .width10 {
            width: 10% !important;
        }

        .width70 {
            width: 80% !important;
        }

        .width80 {
            width: 80% !important;
        }

        .width90 {
            width: 90% !important;
        }

        .container {
            padding: 15px 0;
        }

        .search-wrap .addBtn {
            border-radius: 20px;
            margin-right: 15px;
        }

        .search-wrap .queryBtn {
            margin-left: 15px;
        }

        .el-table .el-input--medium .el-input__inner {
            height: 23px !important;
            line-height: 23px !important;
        }

        .el-table .emptyRow {
            display: inline-block;
            height: 31px !important;
            line-height: 31px !important;
            margin-left: 10px
        }

        .el-form-item {
            margin-bottom: 15px;
        }

        .el-row {
            padding: 0px 30px 0px 15px;
        }

        .detailRecord {
            width: 100%;
            margin: 0px -5px 0px 20px;
        }

        .detailRecord .el-table__body-wrapper::-webkit-scrollbar {
            width: 4px
        }

        .detailRecord .el-table__body-wrapper::-webkit-scrollbar-thumb {
            background: transparent;
            border-radius: 4px
        }

        .detailRecord .el-table__body-wrapper:hover::-webkit-scrollbar-thumb {
            background: hsla(0, 0%, 53%, .4)
        }

        .detailRecord .el-table__body-wrapper:hover::-webkit-scrollbar-track {
            background: hsla(0, 0%, 53%, .1)
        }

        .el-table .el-input--medium .el-input__inner {
            height: 23px !important;
            line-height: 23px !important;
        }

        .el-form-item {
            margin-bottom: 15px;
        }

        table .el-input__inner, table .el-textarea textarea {
            width: 100% !important;
            border: none;
            padding-left: 10px;
            color: black;
            font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "\5FAE\8F6F\96C5\9ED1", Arial, sans-serif !important;
        }

        .dialogBtn {
            width: 100%;
            position: fixed;
            display: flex;
            justify-content: center;
            align-items: center;
            bottom: 0px;
            background-color: #ffffff;
            padding-bottom: 20px;
        }

        .basicInfo {
            color: #364760;
            font-size: 15px;
            margin: 5px 15px 10px 20px;
            background-color: #F0F2F4;
            height: 34px;
            line-height: 34px;
            padding-left: 10px;
        }

        .basicInfo::before {
            content: '';
            display: inline-block;
            width: 4px;
            height: 16px;
            background-color: #364760;
            vertical-align: text-bottom;
            margin-right: 10px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
<div id="app">
    <template>
        <div class="container">
            <el-form ref="commodityInfo" :model="remoteHandler" class="commodity mt-10 width100"
                     label-width="100px">
                <p class="basicInfo" style="position: relative;">已连接设备列表
                    <i class="el-icon-refresh-right" style="cursor: pointer;font-weight: 600!important;"
                       @click="getOnlineDevice"></i>
                    <span style="position: absolute;right: 10px;">
                        <a href="https://www.zjh336.cn/?id=2109" target="_blank"
                           style="margin-right: 5px;color: #2f871a">博客地址</a>
                        <a href="https://gitee.com/zjh336/hz_autojs_toolbox_web/releases" target="_blank"
                           style="margin-right: 5px;color: #2ECC40">Web端本地部署</a>
                        <a href="https://gitee.com/zjh336/hz_autojs_toolbox/releases" target="_blank"
                           style="color: blue;">APP端下载</a>
                        <a href="https://space.bilibili.com/69729485/channel/series" target="_blank"
                           style="margin-right: 5px;color:brown;">演示(操作)视频</a>
                        <a href="https://tool.gljlw.com/qq/?qq=806073526" target="_blank" style="color: #3c663f;">联系QQ:806073526</a>
                    </span>
                </p>
                <el-row>
                    <div class="width100 d-flex a-center">
                        <el-table
                                :data="deviceList"
                                v-loading="deviceLoading"
                                border
                                ref="deviceTable"
                                highlight-current-row
                                @current-change="selectRowChange"
                                style="width: 100%">
                            <el-table-column
                                    prop="deviceUuid"
                                    align="left"
                                    label="设备UUID"
                            >
                                <template slot-scope="{ row, $index}">
                                    {{ row.deviceUuid }}
                                </template>
                            </el-table-column>
                            <el-table-column
                                    prop="connectTime"
                                    label="建立连接时间"
                                    align="left">
                            </el-table-column>
                            <el-table-column
                                    prop="lastHeartTime"
                                    label="最后一次心跳时间"
                                    align="left">
                            </el-table-column>
                            <el-table-column
                                    prop="screenHeight"
                                    label="屏幕高度"
                                    align="left">
                            </el-table-column>
                            <el-table-column
                                    prop="screenWidth"
                                    label="屏幕宽度"
                                    align="left">
                            </el-table-column>
                        </el-table>
                    </div>
                </el-row>
                <el-row style="margin-top: 10px;">
                    <div class="width100 d-flex a-center">
                        <el-form-item label="标准宽度:" prop="x1" class="width20">
                            <el-input type="number"
                                      v-model="deviceInfo.standardWidth"
                                      placeholder="请设置标准宽度"
                                      class="width100" @change="syncWidthHeightToApp"
                            >
                            </el-input>
                        </el-form-item>
                        <el-form-item label="标准高度:" prop="y1" class="width20">
                            <el-input type="number"
                                      v-model="deviceInfo.standardHeight" placeholder="请设置标准高度"
                                      class="width100" @change="syncWidthHeightToApp"
                            >
                            </el-input>
                        </el-form-item>
                        <el-form-item label="x偏移系数:" prop="x1" class="width20">
                            <el-input type="number"
                                      v-model="deviceInfo.offsetX"
                                      placeholder="请设置x偏移系数"
                                      class="width100" @change="syncWidthHeightToApp"
                            >
                            </el-input>
                        </el-form-item>
                        <el-form-item label="y偏移系数:" prop="y1" class="width20">
                            <el-input type="number"
                                      v-model="deviceInfo.offsetY" placeholder="请设置y偏移系数"
                                      class="width100" @change="syncWidthHeightToApp"
                            >
                            </el-input>
                        </el-form-item>
                        <el-form-item label="标准坐标转换:" label-width="120px" class="width10">
                            <el-switch v-model="deviceInfo.standardConvert" @change="syncWidthHeightToApp"/>
                        </el-form-item>
                        <div class="width10 d-flex a-center" style="justify-content: right;margin-bottom:15px;">
                            <el-button @click.stop="syncWidthHeightToApp">同步到APP</el-button>
                        </div>
                    </div>
                </el-row>
                <el-tabs tab-position="left" style="height: auto;margin-top:5px;">
                    <el-tab-pane label="图像处理">
                        <p class="basicInfo">远程图像处理及上传</p>

                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="图片名称:" prop="localImageName" class="width100">
                                    <el-input v-model="remoteHandler.param1.localImageName" placeholder="请输入图片名称"
                                              class="width100"/>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="坐标x1:" prop="x1" class="width25">
                                    <el-input type="number"
                                              v-model="remoteHandler.param1.x1"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="0"
                                              placeholder="请输入坐标值"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="坐标y1:" prop="y1" class="width25">
                                    <el-input type="number"
                                              min="0"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.y1" placeholder="请输入坐标值"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="坐标x2:" prop="x1" class="width25">
                                    <el-input type="number"
                                              v-model="remoteHandler.param1.x2"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="0"
                                              placeholder="请输入坐标值"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="坐标y2:" prop="y2" class="width25">
                                    <el-input type="number"
                                              min="0"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.y2" placeholder="请输入坐标值"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="阈值化相似度:" prop="threshold" class="width50">
                                    <el-input type="number"
                                              :min="0"
                                              :max="255"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.threshold" placeholder="请输入阈值化相似度"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="阈值化最大值:" prop="maxVal" class="width50">
                                    <el-input type="number"
                                              :min="0"
                                              :max="255"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.maxVal" placeholder="请输入阈值化最大值"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="图片相似度:" prop="threshold" class="width25">
                                    <el-input type="number"
                                              min="0"
                                              step="0.1"
                                              max="1"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.imgThreshold" placeholder="请输入图片相似度"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="颜色相似度:" prop="threshold" class="width25">
                                    <el-input type="number"
                                              :min="0"
                                              :max="255"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.colorThreshold" placeholder="请输入颜色相似度"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="大图缩放比例:" prop="bigScale" class="width25">
                                    <el-input type="number"
                                              min="0"
                                              step="0.1"
                                              max="1"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.bigScale" placeholder="请输入大图缩放比例"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="小图缩放比例:" prop="smallScale" class="width25">
                                    <el-input type="number"
                                              min="0"
                                              step="0.1"
                                              max="1"
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              v-model="remoteHandler.param1.smallScale" placeholder="请输入小图缩放比例"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="坐标列表:" class="width40">
                                    <el-input type="textarea" v-model="remoteHandler.param1.positionList" :rows="5"
                                              class="width100">
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="代码预览:" class="width60">
                                    <el-input type="textarea" v-model="remoteHandler.param1.scriptPreview" :rows="5"
                                              class="width100">
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="操作坐标key:" class="width25">
                                    <el-select v-model="remoteHandler.param1.operatePositionKey" class="width100">
                                        <el-option value="x1">x1</el-option>
                                        <el-option value="y1">y1</el-option>
                                        <el-option value="x2">x2</el-option>
                                        <el-option value="y2">y2</el-option>
                                    </el-select>
                                </el-form-item>
                                <el-form-item label="操作坐标值:" class="width25">
                                    <el-input type="number" :min="0" v-model="remoteHandler.param1.operatePositionVal"
                                              class="width100">
                                    </el-input>
                                </el-form-item>
                                <el-form-item class="width50" style="display: flex;justify-content: flex-end;">
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                        <el-radio-group v-model="screenDirection">
                                            <el-radio label="横屏">横屏方向</el-radio>
                                            <el-radio label="竖屏">竖屏方向</el-radio>
                                        </el-radio-group>
                                    </div>
                                    <el-button type="danger" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="setParam1(true)">
                                        坐标全屏
                                    </el-button>
                                    <el-button type="primary" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="readPositionList">
                                        读取坐标列表
                                    </el-button>
                                    <el-button type="primary" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="clearPosition">
                                        清空坐标列表
                                    </el-button>
                                    <el-button type="warning" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="param1Subtract">
                                        减去坐标值
                                    </el-button>
                                    <el-button type="warning" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="param1Addition">
                                        加上坐标值
                                    </el-button>
                                    <!--<el-button type="primary" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="copyPosition">
                                        复制坐标
                                    </el-button>
                                    <el-button type="primary" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="writePosition">
                                        读取坐标
                                    </el-button>-->
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="显示坐标类型" class="width20">
                                    <el-radio-group v-model="positionShowType">
                                        <el-radio label="cur">实际坐标</el-radio>
                                        <el-radio label="standard">转换为标准坐标</el-radio>
                                    </el-radio-group>
                                </el-form-item>
                                <el-form-item prop="previewImg" class="width80 previewImgCls"
                                              style="display: flex;justify-content: flex-end;align-items: center;text-align: center;">
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                        <span>显示浮动控制面板：</span>
                                        <el-switch v-model="remoteHandler.param1.showFixedPositionList"/>
                                    </div>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                        <span>开启快速裁剪：</span>
                                        <el-switch v-model="remoteHandler.param1.isOpenFastClip"
                                                   @change="openFastClipChange"/>
                                    </div>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                        <span>开启灰度化：</span>
                                        <el-switch v-model="remoteHandler.param1.isOpenGray"/>
                                    </div>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                        <span>开启阈值化：</span>
                                        <el-switch v-model="remoteHandler.param1.isOpenThreshold"/>
                                    </div>
                                    <el-button type="primary" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="sendAction('param1','remoteClipGrayscaleAndThresholdToServer')">
                                        图像处理(加载)
                                    </el-button>
                                    <el-button type="primary" style="margin-left:10px" size="mini"
                                               @click.stop.prevent="sendAction('param1','remoteClipGrayscaleAndThresholdAnalysisChartToServer')">
                                        文字识别
                                    </el-button>
                                    <el-button type="info" size="mini" style="margin-left:10px" id="loadPreviewImg"
                                               @click.stop.prevent="loadPreviewImg">加载图片
                                    </el-button>
                                    <el-dropdown trigger="click">
                                        <el-button type="primary" style="margin-left:10px" size="mini">
                                            生成代码(官方)
                                        </el-button>
                                        <el-dropdown-menu slot="dropdown">
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('grayscale')">
                                                灰度化grayscale
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('threshold')">
                                                阈值化threshold
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('clip')">裁图clip
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('findImage')">
                                                找图findImage
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('detectAndComputeFeatures')">
                                                收集特征detectAndComputeFeatures(AutoX不适用)
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('matchFeatures')">
                                                特征匹配matchFeatures(AutoX不适用)
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('findMultiColors')">
                                                多点找色findMultiColors
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('MLKitOCR')">
                                                MLKitOCR文字识别(AutoX不适用)
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('matchTemplate')">
                                                模板匹配matchTemplate
                                            </el-dropdown-item>
                                        </el-dropdown-menu>
                                    </el-dropdown>
                                    <el-dropdown trigger="click">
                                        <el-button type="primary" style="margin-left:10px" size="mini">
                                            生成代码(基础)
                                        </el-button>
                                        <el-dropdown-menu slot="dropdown">
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('getConvertCoefficient')">
                                                获取分辨率转换系数getConvertCoefficient
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('scaleSmallImg')">
                                                按照分辨率缩放小图scaleSmallImg
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('convertXY')">
                                                按照分辨率转换坐标convertXY
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('detectFeaturesScale')">
                                                图片特征匹配detectFeaturesScale(AutoX不适用)
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('matchingFeatures')">
                                                灰度化阈值化特征匹配matchingFeatures(AutoX不适用)
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('randomClick')">
                                                随机点击randomClick
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('grayscaleAndThreshold2')">
                                                灰度化阈值化图片grayscaleAndThreshold2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('grayThresholdFindImg2')">
                                                灰度化阈值化找图grayThresholdFindImg2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('grayThresholdFindMultipleColor2')">
                                                灰度化、阈值化多点找色grayThresholdFindMultipleColor2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('ocrGetContentStr')">
                                                ocr获取文字识别内容字符串结果ocrGetContentStr
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('ocrGetResultToCanvas')">
                                                ocr获取文字识别内容并绘图ocrGetResultToCanvas
                                            </el-dropdown-item>
                                            <el-dropdown-item @click.native.prevent.stop="generateCode('canvasRect')">
                                                绘制方框canvasRect
                                            </el-dropdown-item>
                                        </el-dropdown-menu>
                                    </el-dropdown>
                                    <el-dropdown trigger="click">
                                        <el-button type="primary" style="margin-left:10px" size="mini">
                                            生成代码(进阶)
                                        </el-button>
                                        <el-dropdown-menu slot="dropdown">
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalFindImg2')">
                                                区域找图regionalFindImg2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalClickImg2')">
                                                区域找图点击regionalClickImg2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalAnalysisChart2')">
                                                区域识字获取文字regionalAnalysisChart2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalAnalysisChartPosition2')">
                                                区域识字获取坐标regionalAnalysisChartPosition2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalClickText2')">
                                                区域识字点击regionalClickText2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalMatchTemplate2')">
                                                区域模板匹配regionalMatchTemplate2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalMatchingFeatures')">
                                                区域特征匹配regionalMatchingFeatures
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalMatchFeaturesTemplate')">
                                                区域特征匹配模板regionalMatchFeaturesTemplate
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalClickFeatures')">
                                                区域特征匹配点击regionalClickFeatures
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalFindMultipleColor2')">
                                                区域多点找色regionalFindMultipleColor2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalClickColor2')">
                                                区域多点找色点击regionalClickColor2
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalFindImgOrFeatures')">
                                                区域找图或者特征匹配regionalFindImgOrFeatures
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalMatchTemplateOrMatchFeatures')">
                                                区域模板匹配或者特征匹配模板regionalMatchTemplateOrMatchFeatures
                                            </el-dropdown-item>
                                            <el-dropdown-item
                                                    @click.native.prevent.stop="generateCode('regionalFindCircles2')">
                                                区域灰度化阈值化找圆regionalFindCircles2
                                            </el-dropdown-item>
                                        </el-dropdown-menu>
                                    </el-dropdown>
                                    <el-button type="info" size="mini" style="margin-left:10px"
                                               @click.stop.prevent="execPreviewScript">执行代码
                                    </el-button>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="图片预览:" prop="previewImg" class="width100">
                                    <div class="mousePositionCls" v-show="remoteHandler.param1.previewImg">
                                        <span class="mousePositionX">x:{{imgMousePosition.x }}</span>
                                        <span class="mousePositionY">y:{{imgMousePosition.y}}</span>
                                        <span class="mousePositionColor">color:{{imgMousePosition.color}}</span>
                                    </div>
                                    <div draggable="false"
                                         style="user-select: none;min-height: 40vh;width: 100%;display: flex;justify-content: center;align-items: center;text-align: center;">
                                        <div id="drawArear" class="draw-box" v-if="remoteHandler.param1.previewImg"
                                             style="width: auto;margin: 0; padding: 0;height: auto;max-width: 100%;user-select: none;">
                                            <img id="previewImg" draggable="false"
                                                 style="width: 100%;margin: 0; padding: 0;height: 100%;user-select: none;"
                                                 alt=""/>
                                            <div class="react-box" id="drawReact" draggable="false"
                                                 style="user-select: none;">
                                                <!-- 矩形框 -->
                                            </div>
                                        </div>
                                        <div v-else style="font-size: 20px;color: rgba(29,140,128,0.29)">
                                            暂无图片,请先发送指令,再加载图片
                                        </div>
                                        <canvas id="canvas" style="display:none;"></canvas>
                                    </div>
                                </el-form-item>
                            </div>
                            <div class="positionListFixed" v-show="remoteHandler.param1.showFixedPositionList">
                                <div class="buttonPanel">
                                    <el-button type="primary" size="mini"
                                               @click.stop.prevent="sendAction('param1','remoteClipGrayscaleAndThresholdToServer')">
                                        图像处理(加载)
                                    </el-button>
                                    <el-button type="primary" size="mini"
                                               @click.stop.prevent="sendAction('param1','remoteClipGrayscaleAndThresholdAnalysisChartToServer')">
                                        文字识别
                                    </el-button>
                                    <el-button type="info" size="mini"
                                               @click.stop.prevent="loadPreviewImg">加载图片
                                    </el-button>
                                    <el-button type="danger" size="mini"
                                               @click.stop.prevent="setParam1(true)">
                                        坐标全屏
                                    </el-button>
                                    <el-button type="primary" size="mini"
                                               @click.stop.prevent="readPositionList">
                                        读取坐标列表
                                    </el-button>
                                    <el-button type="primary" size="mini"
                                               @click.stop.prevent="clearPosition">
                                        清空坐标列表
                                    </el-button>
                                </div>
                                <el-input class="positionTextarea" type="textarea"
                                          v-model="remoteHandler.param1.positionList">
                                </el-input>
                            </div>
                        </el-row>
                    </el-tab-pane>
                    <el-tab-pane label="布局分析">
                        <p class="basicInfo">远程布局分析及上传</p>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="UI选择器:" class="width50">
                                    <el-checkbox-group v-model="remoteHandler.param5.uiSelect">
                                        <el-checkbox label="id">id选择器</el-checkbox>
                                        <el-checkbox label="text">text选择器</el-checkbox>
                                        <el-checkbox label="desc">desc选择器</el-checkbox>
                                        <el-checkbox label="className">className选择器</el-checkbox>
                                    </el-checkbox-group>
                                </el-form-item>
                                <el-form-item label="选择器条件:" class="width50">
                                    <el-radio-group v-model="remoteHandler.param5.uiSelectCondition">
                                        <el-radio label="findOne">找到一个(阻塞)findOne</el-radio>
                                        <el-radio label="findOnce">找到第N个findOnce</el-radio>
                                        <el-radio label="untilFind">找到所有untilFind</el-radio>
                                        <el-radio label="waitFor">等待出现waitFor</el-radio>
                                        <el-radio label="exists">存在exists</el-radio>
                                    </el-radio-group>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="动作:" class="width50">
                                    <el-radio-group v-model="remoteHandler.param5.uiSelectAction">
                                        <el-radio label="click">点击click</el-radio>
                                        <el-radio label="clickCenter">点击中心clickCenter</el-radio>
                                        <el-radio label="longClick">长按longClick</el-radio>
                                    </el-radio-group>
                                </el-form-item>
                                <el-form-item label="开启点击生成代码:" label-width="140px" class="width50">
                                    <el-switch v-model="remoteHandler.param5.openClickGenerateCode"/>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="代码预览:" class="width60">
                                    <el-input type="textarea" v-model="remoteHandler.param5.scriptPreview" :rows="5"
                                              placeholder="请点击控件后生成代码"
                                              class="width100">
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="控件信息:" class="width40">
                                    <el-input type="textarea" v-model="remoteHandler.param5.nodeInfo" :rows="5"
                                              placeholder="点击控件信息快速获取文本内容"
                                              class="width100">
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center"
                                 style="display: flex;justify-content: flex-start;align-items: center;text-align: center;">
                                <div>
                                    <el-button type="primary"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="remoteLayoutAnalysis">
                                        远程布局分析
                                    </el-button>
                                    <el-button type="primary"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="remoteLimitLayoutAnalysis">
                                        远程限制应用布局分析
                                    </el-button>
                                    <el-button type="primary"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="uploadAndLoadNodeJson">
                                        上传布局分析并解析
                                    </el-button>
                                    <el-button type="info"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="loadNodeJson">
                                        解析布局分析
                                    </el-button>
                                    <el-button type="warning"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="clearNodeJson(true)">
                                        清空布局分析
                                    </el-button>
                                    <el-button type="primary"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="execNodePreviewScript">
                                        执行代码
                                    </el-button>
                                    <el-button type="warning"
                                               style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                               size="mini"
                                               @click.stop.prevent="clearNodePreviewScript">
                                        清空代码
                                    </el-button>
                                    <el-checkbox
                                            style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px"
                                            v-model="remoteHandler.param5.checkAll" @change="checkAllNode">全选
                                    </el-checkbox>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px">
                                        <span style="margin-right: 5px;">父子不相关联</span>
                                        <el-switch v-model="remoteHandler.param5.checkStrictly"/>
                                    </div>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px">
                                        <span style="margin-right: 5px;">只显示可见控件</span>
                                        <el-switch v-model="remoteHandler.param5.isOnlyShowVisible"
                                                   @change="onlyShowVisible"/>
                                    </div>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px">
                                        <span style="margin-right: 5px;">只显示屏幕范围内控件</span>
                                        <el-switch v-model="remoteHandler.param5.isOnlyShowInScreen"
                                                   @change="onlyShowInScreen"/>
                                    </div>
                                    <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px">
                                        <span style="margin-right: 5px;">绘制背景图片</span>
                                        <el-switch v-model="remoteHandler.param5.isShowBgImg" @change="showDrawBgImg"/>
                                    </div>
                                </div>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center mt-1">
                                <el-tree :data="remoteHandler.param5.rootNodeObj"
                                         :props="remoteHandler.param5.defaultProps"
                                         empty-text="请先上传控件或加载控件"
                                         default-expand-all
                                         :highlight-current="true"
                                         ref="nodeTree"
                                         :show-checkbox="true"
                                         node-key="nodeKey"
                                         :check-on-click-node="false"
                                         :filter-node-method="filterNode"
                                         :check-strictly="remoteHandler.param5.checkStrictly"
                                         @check="nodeCheckFun"
                                         @node-click="nodeClickFun"
                                         @current-change="currentChangeFun"
                                         class="nodeTreeClass nodeDivCommon"></el-tree>
                                <div class="nodePreviewClass nodeDivCommon">
                                    <img id="nodePreviewImg" draggable="false"
                                         style="display: none;"/>
                                    <canvas v-if="remoteHandler.param5.rootNodeJson" id="nodePreviewCanvas"
                                            style="width: 100%;margin: 0; padding: 0;"></canvas>
                                    <div v-else style="width: 100%;
                                                height: 100%;
                                                display: flex;
                                                justify-content: center;
                                                align-items: center;
                                                color: #909399;">请先上传控件或加载控件
                                    </div>
                                </div>
                                <div class="nodeDetailDiv nodeDivCommon">
                                    <template v-if="remoteHandler.param5.dialogVisible">
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">className:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.className }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">packageName:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.packageName
                                                }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">text:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.text }}</div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">desc:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.desc }}</div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">id:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.id }}</div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">sourceNodeId:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.sourceNodeId
                                                }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">bounds:</div>
                                            <div class="contentClass"> {{
                                                '['+remoteHandler.param5.selectNode.boundsInfo.left+','+
                                                remoteHandler.param5.selectNode.boundsInfo.top+',' +
                                                remoteHandler.param5.selectNode.boundsInfo.right + ',' +
                                                remoteHandler.param5.selectNode.boundsInfo.bottom + ']'}}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">depth:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.depth }}</div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">checkable:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.checkable }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">checked:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.checked }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">focusable:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.focusable }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">focused:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.focused }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">accessibilityFocused:</div>
                                            <div class="contentClass">{{
                                                remoteHandler.param5.selectNode.accessibilityFocused }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">selected:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.selected }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">clickable:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.clickable }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">drawingOrder:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.drawingOrder
                                                }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">longClickable:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.longClickable
                                                }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">enabled:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.enabled }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">password:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.password }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">scrollable:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.scrollable }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">visible:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.visible }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">column:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.column }}</div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">columnCount:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.columnCount
                                                }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">columnCount:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.columnCount
                                                }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">columnSpan:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.columnSpan }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">row:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.row }}</div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">rowCount:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.rowCount }}
                                            </div>
                                        </el-row>
                                        <el-row class="nodeDetailRow">
                                            <div class="labelClass">rowSpan:</div>
                                            <div class="contentClass">{{ remoteHandler.param5.selectNode.rowSpan }}
                                            </div>
                                        </el-row>
                                    </template>
                                    <template v-else>
                                        <div style="width: 100%;
                                                height: 100%;
                                                display: flex;
                                                justify-content: center;
                                                align-items: center;
                                                color: #909399;">请点击控件节点或者图中矩形
                                        </div>
                                    </template>
                                </div>
                            </div>
                        </el-row>
                    </el-tab-pane>
                    <el-tab-pane label="远程脚本">
                        <p class="basicInfo">远程脚本执行</p>
                        <el-row>
                            <div class="width100 d-flex a-start">
                                <el-form-item label="脚本内容:" prop="scriptText" class="width100">
                                    <el-input v-model="remoteHandler.param4.scriptText" :rows="10" type="textarea"
                                              placeholder="请输入脚本内容" class="width100"/>
                                </el-form-item>
                                <el-button type="primary" size="mini" style="margin-left:10px" id="remoteRunScript"
                                           @click.stop.prevent="sendAction('param4','remoteExecScript')">运行脚本
                                </el-button>
                            </div>
                        </el-row>
                    </el-tab-pane>
                    <el-tab-pane label="预览设备">
                        <p class="basicInfo">预览设备</p>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="预览质量:" prop="imgQuality" class="width25">
                                    <el-input type="number"
                                              v-model="devicePreviewParam.imgQuality" placeholder=""
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="0"
                                              max="100"
                                              @change="autoDevicePreview"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="缩放倍数:" prop="scale" class="width25">
                                    <el-input type="number"
                                              v-model="devicePreviewParam.imgScale" placeholder=""
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="0"
                                              step="0.1"
                                              max="1"
                                              @change="autoDevicePreview"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="预览高度:" prop="scale" class="width25">
                                    <el-input type="number"
                                              v-model="devicePreviewParam.previewHeight" placeholder=""
                                              min="0"
                                              max="5000"
                                              @change="autoDevicePreview"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="预览阈值:" prop="scale" class="width25">
                                    <el-input type="number"
                                              v-model="devicePreviewParam.imgThreshold" placeholder=""
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="0"
                                              max="255"
                                              @change="autoDevicePreview"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="APP刷新:" prop="appSpace" class="width25">
                                    <el-input type="number"
                                              v-model="devicePreviewParam.appSpace" placeholder=""
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="10"
                                              step="10"
                                              max="5000"
                                              @change="autoDevicePreview"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="浏览器刷新:" prop="clientSpace" class="width25">
                                    <el-input type="number"
                                              v-model="devicePreviewParam.clientSpace" placeholder=""
                                              oninput="if(value.length>10)value=value.slice(0,10)"
                                              min="10"
                                              step="10"
                                              max="5000"
                                              @change="autoDevicePreview"
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                                <el-form-item label="操作记录:" prop="clientSpace" class="width50">
                                    <el-input type="textarea"
                                              v-model="devicePreviewParam.operateRecord" placeholder=""
                                              class="width100"
                                    >
                                    </el-input>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="设备预览:" prop="previewImg" class="width100">
                                    <div>x:{{deviceMousePosition.x }} y:{{deviceMousePosition.y}}</div>
                                    <div style="display: flex;justify-content: flex-end;align-items: center;text-align: center;width: 100%">
                                        <el-button type="warning" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="fixedOperate('home')">主页
                                        </el-button>
                                        <el-button type="warning" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="fixedOperate('back')">返回
                                        </el-button>
                                        <el-button type="warning" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="fixedOperate('recents')">任务
                                        </el-button>
                                        <el-button type="warning" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="fixedOperate('quickSettings')">通知
                                        </el-button>
                                        <el-button type="warning" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="fixedOperate('powerDialog')">电源
                                        </el-button>
                                        <el-button type="info" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="devicePreviewParam.operateRecord = ''">清空操作记录
                                        </el-button>
                                    </div>
                                    <div style="display: flex;justify-content: flex-end;align-items: center;text-align: center;width: 100%">
                                        <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                            <span>开启灰度化：</span>
                                            <el-switch v-model="devicePreviewParam.isOpenGray"
                                                       @change="autoDevicePreview"/>
                                        </div>
                                        <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                            <span>开启阈值化：</span>
                                            <el-switch v-model="devicePreviewParam.isOpenThreshold"
                                                       @change="autoDevicePreview"/>
                                        </div>
                                        <div style="display: inline-flex;justify-content: flex-end;align-items: center;margin-left:10px;">
                                            <span>参数变化后自动预览：</span>
                                            <el-switch v-model="devicePreviewParam.valueUpdateAfterAutoPreview"/>
                                        </div>
                                        <el-button type="primary" size="mini" style="margin-left:10px"
                                                   id="loadPreviewImg"
                                                   @click.stop.prevent="startPreviewDevice(true)">开始预览
                                        </el-button>
                                        <el-button type="info" size="mini" style="margin-left:10px"
                                                   @click.stop.prevent="stopPreviewDevice(true)">停止预览
                                        </el-button>
                                    </div>
                                    <div style="min-height: 40vh;width: 100%;display: flex;justify-content: center;align-items: center;text-align: center;">
                                        <div style="font-size: 20px;color: rgba(29,140,128,0.29)">
                                            <img id="devicePreviewImg" draggable="false"
                                                 style="width: auto;margin: 0; padding: 0;height: 500px;max-width: 100%;"/>
                                        </div>
                                    </div>
                                </el-form-item>
                            </div>
                        </el-row>
                    </el-tab-pane>
                    <el-tab-pane label="远程日志">
                        <p class="basicInfo">远程日志上传</p>
                        <el-row>
                            <div class="width100 d-flex a-start">
                                <el-form-item label="日志名称:" prop="logName" class="width100">
                                    <el-input v-model="remoteHandler.param2.logName" placeholder="请输入远程日志名称"
                                              class="width100"/>
                                </el-form-item>
                            </div>
                        </el-row>
                        <el-row>
                            <div class="width100 d-flex a-center">
                                <el-form-item label="日志预览:" prop="previewLog" class="width100">
                                    <div style="display: inline-flex;width: 100%;">
                                        <!--<div style="display: inline-flex;justify-content: flex-start;align-items: center;flex: 1;">
                                            <el-button type="danger" style="margin-left:10px" size="mini"
                                                       @click.stop.prevent="sendAction('param3','remoteRestartScript','script')">
                                                远程重启脚本
                                            </el-button>
                                            <el-button type="danger" style="margin-left:10px;" size="mini"
                                                       @click.stop.prevent="sendAction('param3','remoteRestartScript','mainScript')">
                                                远程重启主程序
                                            </el-button>
                                        </div>-->
                                        <div style="display: inline-flex;justify-content: flex-end;align-items: center;text-align: center;flex:1">
                                            <el-button type="primary" style="margin-left:10px" size="mini"
                                                       @click.stop.prevent="sendAction('param2','remoteUploadLogToServer')">
                                                远程日志上传
                                            </el-button>
                                            <a href="remoteHandler.param2.previewLog"/>
                                            <el-button type="primary" style="margin-left:10px" size="mini"
                                                       @click.stop.prevent="downLoadLog">
                                                日志下载
                                            </el-button>
                                            <el-button type="info" size="mini" style="margin-left:10px"
                                                       id="loadRemoteLog"
                                                       @click.stop.prevent="loadPreviewLog">加载日志
                                            </el-button>
                                        </div>
                                    </div>
                                    <div style="min-height: 40vh;display: flex;justify-content: flex-end;align-items: center;text-align: center;width: 100%">
                                        <iframe frameborder="no" border="0" marginwidth="0" marginheight="0"
                                                height="100%"
                                                width="100%" style="height: 70vh;"
                                                allowtransparency="yes" v-if="remoteHandler.param2.previewLog"
                                                id="previewLog"
                                                src="">
                                        </iframe>
                                        <div v-else style="font-size: 20px;color: rgba(29,140,128,0.29)">
                                            暂无日志,请先发送指令,再加载日志
                                        </div>
                                    </div>
                                </el-form-item>
                            </div>
                        </el-row>
                    </el-tab-pane>
                </el-tabs>
            </el-form>

        </div>
    </template>
</div>
<script type="module">
    import {getContext, sortByKey, rgb2hex, zeroFill} from "../../utils/utils.js";
    // 挂载到window对象中
    window.ZXW_VUE = new Vue({
        el: '#app',
        data: {
            loadingIndex: 0,
            deviceList: [],// 设备列表
            deviceLoading: true,
            imageRandomKey: Math.random(),
            logRandomKey: Math.random(),
            otherProperty: {
                orientation: 1  // 屏幕方向
            },// 其他属性对象 同步app端
            deviceInfo: {
                startPreview: false,
                deviceUuid: '',
                standardWidth: null,
                standardHeight: null,
                standardConvert: false,
                offsetX: 0,
                offsetY: 0
            },// 当前设备信息
            positionShowType: 'cur', // 坐标显示类型
            screenDirection: '横屏',
            devicePreviewParam: { // 设备预览参数
                imgQuality: 10,
                imgScale: 1,
                previewHeight: 500,
                isOpenGray: false,
                isOpenThreshold: false,
                imgThreshold: 60, // 图片阈值相似度
                appSpace: 500,
                clientSpace: 500,
                valueUpdateAfterAutoPreview: false,
                operateRecord: ''
            },
            deviceMousePosition: { // 设备鼠标坐标
                x: 0,
                y: 0
            },
            imgMousePosition: {// 图片鼠标坐标
                x: 0,
                y: 0,
                color: ''
            },
            remoteHandler: {
                param1: {
                    x1: 0,
                    y1: 0,
                    x2: 1080,
                    y2: 2400,
                    cache_x1: 0,
                    cache_y1: 0,
                    cache_x2: 1080,
                    cache_y2: 2400,
                    threshold: 60,
                    maxVal: 255,
                    imgThreshold: 0.7,// 图片相似度
                    colorThreshold: 26,// 颜色相似度
                    bigScale: 1,
                    smallScale: 1,
                    localImageName: 'allScreen.png',
                    scriptPreview: '',
                    previewImg: '',
                    isOpenFastClip: false,
                    isOpenGray: false,
                    isOpenThreshold: false,
                    isOpenColor: false,
                    showFixedPositionList: false,
                    positionList: '',// 坐标列表
                    operatePositionKey: 'x1',// 操作key
                    operatePositionVal: 100,// 操作坐标值
                },
                param2: {
                    logName: 'log2022072121.txt',
                    previewLog: ''
                },
                param4: {
                    scriptText: ''
                },
                param5: {
                    rootNodeJson: '',
                    rootNodeObj: [],
                    nodeKeyArr: [],// key数组
                    selectNode: {},
                    rectCanvasArr: [],// 绘制方框数组
                    highlightRect: null,// 高亮方框
                    dialogVisible: false,
                    isOnlyShowVisible: true,
                    isOnlyShowInScreen: true,
                    isShowBgImg: true,
                    checkAll: false,//全选
                    scriptPreview: '',// 代码预览
                    openClickGenerateCode: false,// 开启点击生成代码
                    nodeInfo: '',// 节点信息
                    uiSelect: ['id', 'text', 'desc', 'className'],// ui选择器
                    uiSelectCondition: 'findOne',// ui选择器条件
                    uiSelectAction: 'click',// 动作
                    checkStrictly: true,// 父子相关联
                    defaultProps: {
                        children: 'children',
                        label: 'label'
                    },
                    nodeType: 'tree'
                }
            },
            dialogVisible: false
        },
        computed: {
            param5DialogVisible() {
                return this.remoteHandler.param5.dialogVisible;
            }
        },
        watch: {
            otherProperty(val) {
                if (!val) {
                    return;
                }
                this.screenDirection = val.orientation === 1 ? "竖屏" : "横屏";
            },
            param5DialogVisible(val) {
                if (val) {
                    $(".nodeDetailDiv").on("click", ".contentClass", this.nodeContentClick);
                } else {
                    $(".nodeDetailDiv").off("click");
                }
            }
        },
        mounted() {
            this.getOnlineDevice();
            // 每2秒同步一次其他属性
            setInterval(() => {
                this.timeSyncOtherProperty()
            }, 3 * 1000)
        },
        methods: {
            // 选中行
            selectRowChange(row) {
                // 初始化设备
                let initDevice = (row) => {
                    this.$set(row, 'standardWidth', row.screenWidth);
                    this.$set(row, 'standardHeight', row.screenHeight);
                    this.$set(row, 'standardConvert', false);
                    this.$set(row, 'offsetX', 0);
                    this.$set(row, 'offsetY', 0);
                    this.deviceInfo = row;
                    this.$set(this.deviceInfo, 'standardWidth', row.screenWidth);
                    this.$set(this.deviceInfo, 'standardHeight', row.screenHeight);
                    this.$set(this.deviceInfo, 'standardConvert', false);
                    this.$set(this.deviceInfo, 'offsetX', 0);
                    this.$set(this.deviceInfo, 'offsetY', 0);
                    this.screenDirection = row.orientation === 1 ? "竖屏" : "横屏";
                    // 默认当前时间日志
                    this.remoteHandler.param2.logName = "log" + this.getLastHeartTimeStr() + ".txt";
                    setTimeout(() => {
                        // 坐标全屏
                        this.setParam1(true);
                    }, 3000);
                    window.ZXW_VUE.$notify.success({
                        message: "已选择设备:" + row.deviceUuid,
                        duration: '3000'
                    })
                };
                // 清空选中行
                let clearSelectRow = () => {
                    window.ZXW_VUE.$nextTick(() => {
                        window.ZXW_VUE.$refs["deviceTable"].setCurrentRow()
                    })
                };
                let _that = this;
                // 验证密码
                let validPassword = () => {
                    // 输入密码
                    window.ZXW_VUE.$prompt('请输入APP端设置的访问密码', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消'
                    }).then(({value}) => {
                        $.ajax({
                            url: getContext() + "/device/validPassword",
                            type: "GET",
                            dataType: "json",
                            data: {
                                "deviceUUID": row.deviceUuid,
                                "password": value
                            },
                            success: function (data) {
                                if (data) {
                                    if (data.isSuccess) {
                                        // 密码正确
                                        if (data.data) {
                                            initDevice(row)
                                        } else {
                                            clearSelectRow();
                                            window.ZXW_VUE.$notify.error({
                                                message: "访问密码不正确",
                                                duration: '1000'
                                            })
                                        }
                                    }
                                }
                            },
                            error: function (msg) {
                                clearSelectRow();
                            }
                        });
                    }).catch(() => {
                    });
                };
                $.ajax({
                    url: getContext() + "/device/isNeedPassword",
                    type: "GET",
                    dataType: "json",
                    data: {
                        "deviceUUID": row.deviceUuid
                    },
                    success: function (data) {
                        if (data) {
                            if (data.isSuccess) {
                                // 不需要密码
                                if (!data.data) {
                                    initDevice(row)
                                } else {
                                    // 验证密码
                                    validPassword();
                                }
                            }
                        }
                    },
                    error: function (msg) {
                    }
                });
            },
            // 获取在线设备
            getOnlineDevice() {
                let _this = this;
                _this.deviceLoading = true;
                $.ajax({
                    url: getContext() + "/device/getOnlineDevice",
                    type: "POST",
                    dataType: "json",
                    contentType: "application/json",
                    success: function (data) {
                        if (data) {
                            if (data.isSuccess) {
                                _this.deviceList = data.data;
                            }
                        }
                        setTimeout(() => {
                            _this.deviceLoading = false
                        }, 200)
                    },
                    error: function (msg) {
                        setTimeout(() => {
                            _this.deviceLoading = false
                        }, 200)
                    }
                });
            },
            // 验证是否已选设备
            validSelectDevice() {
                if (!this.deviceInfo.deviceUuid) {
                    window.ZXW_VUE.$message.warning('请先选择设备');
                    return false;
                }
                return true;
            },
            // 定时同步其他属性
            timeSyncOtherProperty() {
                if (!this.deviceInfo.deviceUuid) {
                    return
                }
                let _that = this;
                $.ajax({
                    url: getContext() + "/device/getOtherPropertyJson",
                    type: "GET",
                    dataType: "json",
                    data: {
                        "deviceUUID": this.deviceInfo.deviceUuid
                    },
                    success: function (data) {
                        if (data) {
                            if (data.isSuccess) {
                                // json字符串
                                let json = data.data;
                                if (json) {
                                    // 解析对象
                                    _that.otherProperty = JSON.parse(json);
                                }
                            }
                        }
                    },
                    error: function (msg) {
                    }
                });
            },
            // 同步标准宽高到App
            syncWidthHeightToApp() {
                if (!this.validSelectDevice()) {
                    return
                }
                let script = "commonStorage.put('x偏移系数'," + this.deviceInfo.offsetX + ");commonStorage.put('y偏移系数'," + this.deviceInfo.offsetY + ");commonStorage.put('standardConvert'," + this.deviceInfo.standardConvert + ");commonStorage.put('standardWidth'," + this.deviceInfo.standardWidth + ");commonStorage.put('standardHeight'," + this.deviceInfo.standardHeight + ");events.broadcast.emit('refreshUI');";
                this.sendAction('param5', 'remoteExecScript', script)
            },
            // 获取最后一次心跳时间字符串
            getLastHeartTimeStr() {
                let date = new Date(this.deviceInfo.lastHeartTime);//当前时间
                let month = zeroFill(date.getMonth() + 1);//月
                let day = zeroFill(date.getDate());//日
                let hour = zeroFill(date.getHours());//时
                //当前时间
                return date.getFullYear() + month + day
                    + hour;
            }
            // 发送消息到客户端
            sendMsgToClient(action, messageStr, callback) {
                if (!this.validSelectDevice()) {
                    return
                }
                let dataParam = {
                    action: action,
                    deviceUuid: this.deviceInfo.deviceUuid,
                    message: btoa(messageStr)
                };
                let that = this;
                $.ajax({
                    url: getContext() + "/device/sendMessageToClient",
                    type: "POST",
                    dataType: "json",
                    contentType: "application/json",
                    data: JSON.stringify(dataParam),
                    success: function (data) {
                        if (data) {
                            if (data.isSuccess) {
                                if (callback) {
                                    callback()
                                }
                            } else {
                                console.log("发送失败", data.message)
                            }
                        }
                    },
                    error: function (msg) {
                    }
                });
            },
            // 发送指令
            sendAction(paramKey, functionName, paramVal) {
                if (!this.validSelectDevice()) {
                    return
                }
                let messageStr = "";
                if ("param1" === paramKey) {
                    this.remoteHandler.param1.cache_x1 = this.remoteHandler.param1.x1;
                    this.remoteHandler.param1.cache_y1 = this.remoteHandler.param1.y1;
                    this.remoteHandler.param1.cache_x2 = this.remoteHandler.param1.x2;
                    this.remoteHandler.param1.cache_y2 = this.remoteHandler.param1.y2;
                    messageStr = '{"functionName":"' + functionName + '","functionParam":[' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',"' + this.remoteHandler.param1.localImageName + '",' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ']}';
                } else if ("param2" === paramKey) {
                    messageStr = '{"functionName":"' + functionName + '","functionParam":["' + this.remoteHandler.param2.logName + '"]}';
                } else if ("param3" === paramKey) {
                    messageStr = '{"functionName":"' + functionName + '","functionParam":["' + paramVal + '"]}';
                } else if ("param4" === paramKey) {
                    messageStr = '{"functionName":"' + functionName + '","functionParam":["' + encodeURIComponent(this.remoteHandler.param4.scriptText) + '"]}';
                } else if ("param5" === paramKey) {
                    messageStr = '{"functionName":"' + functionName + '","functionParam":["' + encodeURIComponent(paramVal) + '"]}';
                }
                let dataParam = {
                    action: "remoteHandler",
                    deviceUuid: this.deviceInfo.deviceUuid,
                    message: btoa(messageStr)
                };
                let that = this;
                $.ajax({
                    url: getContext() + "/device/sendMessageToClient",
                    type: "POST",
                    dataType: "json",
                    contentType: "application/json",
                    data: JSON.stringify(dataParam),
                    success: function (data) {
                        if (data) {
                            if (data.isSuccess) {
                                window.ZXW_VUE.$notify.success({
                                    message: '发送成功',
                                    duration: '1000'
                                });
                                setTimeout(() => {
                                    if ("param1" === paramKey) {
                                        that.loadPreviewImg()
                                    } else if ("param2" === paramKey) {
                                        that.loadPreviewLog()
                                    }
                                }, 1200)
                            } else {
                                window.ZXW_VUE.$notify.error({
                                    message: data.msg,
                                    duration: '1000'
                                })
                            }
                        }
                    },
                    error: function (msg) {
                    }
                });
            },
            // 多点坐标转换
            multipleConvert() {
                let positionList = this.remoteHandler.param1.positionList;
                let tempArr = (positionList || '').split('\n') || [];
                if (tempArr.length === 0) {
                    return;
                }
                // 例子 基于第一个点的坐标偏移值 [[35, 30, "#FFFFFF"], [-28, -2, "#000000"], [-23, 20, "#000000"]]
                let multipleArr = [];
                // 获取第一个点
                let firstPoint = tempArr[0];
                // 第一个点数组
                let firstPointArr = firstPoint.split(',') || [];
                let firstX = firstPointArr[0];
                let firstY = firstPointArr[1];
                let firstColor = firstPointArr[2];
                for (let i = 1; i < tempArr.length; i++) {
                    let curPoint = tempArr[i];
                    if (!curPoint) {
                        continue;
                    }
                    // 当前点的数组
                    let curPointArr = curPoint.split(',') || [];

                    let curX = curPointArr[0];
                    let curY = curPointArr[1];
                    let curColor = curPointArr[2];
                    // 添加元素
                    multipleArr.push([(curX - firstX), (curY - firstY), curColor])
                }
                return '"' + firstColor + '",' + JSON.stringify(multipleArr);
            },


            //参数1坐标值减去固定值
            param1Subtract() {
                this.remoteHandler.param1[this.remoteHandler.param1.operatePositionKey] = Number(this.remoteHandler.param1[this.remoteHandler.param1.operatePositionKey]) - Number(this.remoteHandler.param1.operatePositionVal);
            },
            //参数1坐标值加上固定值
            param1Addition() {
                this.remoteHandler.param1[this.remoteHandler.param1.operatePositionKey] = Number(this.remoteHandler.param1[this.remoteHandler.param1.operatePositionKey]) + Number(this.remoteHandler.param1.operatePositionVal);
            },
            // 坐标全屏
            setParam1(showMessage) {
                if (!this.validSelectDevice()) {
                    return
                }
                if ("竖屏" === this.screenDirection) {
                    this.remoteHandler.param1.x1 = 0;
                    this.remoteHandler.param1.y1 = 0;
                    this.remoteHandler.param1.x2 = this.deviceInfo.screenWidth;
                    this.remoteHandler.param1.y2 = this.deviceInfo.screenHeight;
                } else {
                    this.remoteHandler.param1.x1 = 0;
                    this.remoteHandler.param1.y1 = 0;
                    this.remoteHandler.param1.x2 = this.deviceInfo.screenHeight;
                    this.remoteHandler.param1.y2 = this.deviceInfo.screenWidth;
                }
                if (showMessage) {
                    window.ZXW_VUE.$notify.success({message: '操作成功', duration: '1000'});
                }
            },
            // 清空坐标
            clearPosition() {
                this.remoteHandler.param1.positionList = '';
                window.ZXW_VUE.$notify.success({message: '清空坐标成功', duration: '1000'})
            },
            // 读取坐标
            readPositionList() {
                let positionList = this.remoteHandler.param1.positionList;
                let tempArr = (positionList || '').split('\n') || [];
                if (tempArr.length >= 1) {
                    let arr = (tempArr[0] || '').split(',') || [];
                    if (arr.length >= 1) {
                        this.remoteHandler.param1.x1 = arr[0] ? (Number(arr[0].replace(/\s/g, "")) || 0) : 0;
                    }
                    if (arr.length >= 2) {
                        this.remoteHandler.param1.y1 = arr[1] ? (Number(arr[1].replace(/\s/g, "")) || 0) : 0;
                    }
                }
                if (tempArr.length >= 2) {
                    let arr = (tempArr[1] || '').split(',') || [];
                    if (arr.length >= 1) {
                        this.remoteHandler.param1.x2 = arr[0] ? (Number(arr[0].replace(/\s/g, "")) || 0) : 0;
                    }
                    if (arr.length >= 2) {
                        this.remoteHandler.param1.y2 = arr[1] ? (Number(arr[1].replace(/\s/g, "")) || 0) : 0;
                    }
                }
                window.ZXW_VUE.$notify.success({message: '读取坐标成功', duration: '1000'})
            },
            // 开启快速裁图change方法
            openFastClipChange(val) {
                // 开启
                if (val) {
                    // 自动设置全屏
                    this.setParam1(false);
                }
            },
            // 加载预览图片
            loadPreviewImg() {
                if (!this.validSelectDevice()) {
                    return
                }
                this.remoteHandler.param1.previewImg = "";
                let imgUrl = getContext() + "/uploadPath/autoJsTools/" + this.deviceInfo.deviceUuid + "/" + this.remoteHandler.param1.localImageName;
                let _this = this;
                this.remoteHandler.param1.cache_x1 = this.remoteHandler.param1.x1;
                this.remoteHandler.param1.cache_y1 = this.remoteHandler.param1.y1;
                this.remoteHandler.param1.cache_x2 = this.remoteHandler.param1.x2;
                this.remoteHandler.param1.cache_y2 = this.remoteHandler.param1.y2;
                setTimeout(() => {
                    this.remoteHandler.param1.previewImg = imgUrl;
                    this.$nextTick(() => {
                        $("#previewImg").attr("src", imgUrl + "?t=" + new Date().getTime());

                        let drawBox = document.querySelector('#drawArear');
                        window.drawFlag = false;
                        let drawReact = document.getElementById('drawReact'); // 获取矩形框元素
                        drawReact.style.visibility = 'hidden';
                        drawReact.style.width = '0px'; // 宽
                        drawReact.style.height = '0px'; // 高
                        drawReact.style.left = '0px';
                        drawReact.style.top = '0px';

                        drawBox.removeEventListener('mousemove', _this.drawMouseMove);
                        drawBox.addEventListener('mousemove', _this.drawMouseMove);

                        drawBox.removeEventListener('mousedown', _this.drawMouseDown);
                        drawBox.addEventListener('mousedown', _this.drawMouseDown, true);

                        drawBox.removeEventListener('click', _this.imgMouseClick);
                        drawBox.addEventListener('click', _this.imgMouseClick);


                        let img = new Image();
                        img.src = imgUrl + "?t=" + new Date().getTime();
                        let canvas = document.getElementById('canvas');
                        canvas.width = this.remoteHandler.param1.cache_x2 - this.remoteHandler.param1.cache_x1;
                        canvas.height = this.remoteHandler.param1.cache_y2 - this.remoteHandler.param1.cache_y1;
                        window.ctx = canvas.getContext('2d');
                        img.onload = function () {
                            // 在canvas上画图片
                            window.ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
                        };
                    });
                }, 200);
            },
            // 图片鼠标点击
            imgMouseClick() {
                let positionList = this.remoteHandler.param1.positionList;
                positionList += (this.imgMousePosition.x + "," + this.imgMousePosition.y + "," + this.imgMousePosition.color + "\n");
                if (window.ctx) {
                    // 获取图片像素信息
                    let pixel = window.ctx.getImageData(this.imgMousePosition.x, this.imgMousePosition.y, 1, 1);
                    let data = pixel.data;
                    // 获取rgba值
                    let rgba = 'rgba(' + data[0] + ',' + data[1] + ',' + data[2] + ',' + (data[3] / 255) + ')';
                    // 设置小正方形的背景颜色
                    console.log(this.rgb2hex(rgba));
                }
                this.remoteHandler.param1.positionList = positionList
            },
            // 绘画鼠标按下
            drawMouseDown(e) {
                if (!this.remoteHandler.param1.isOpenFastClip) {
                    return;
                }
                let drawArear = document.getElementById('drawArear'); // 获取画布元素
                let drawReact = document.getElementById('drawReact'); // 获取矩形框元素
                let areaInfo = drawArear.getBoundingClientRect();
                if (!window.drawFlag) {
                    window.drawFlag = true;
                    drawReact.style.visibility = 'hidden';
                    drawReact.style.width = '0px'; // 宽
                    drawReact.style.height = '0px'; // 高
                    drawReact.style.left = '0px';
                    drawReact.style.top = '0px';
                    drawReact.style.visibility = 'visible'; // 进入画布按下鼠标显示默认矩形框
                    // 鼠标按下的位置作为矩形框的顶点
                    window.beginPoint = {x: e.clientX - areaInfo.x, y: e.clientY - areaInfo.y};
                    window.reactTop = e.clientY - areaInfo.y;
                    window.reactLeft = e.clientX - areaInfo.x;
                    drawReact.style.top = window.reactTop + 'px';
                    drawReact.style.left = window.reactLeft + 'px';
                } else {
                    window.drawFlag = false;
                    // 鼠标弹起的点作为矩形框的终点
                    window.endPoint = {x: e.clientX - areaInfo.x, y: e.clientY - areaInfo.y};
                    drawReact.style.visibility = 'hidden';
                    // 触发读取坐标操作
                    setTimeout(() => {
                        // 获取坐标列表
                        let positionList = (this.remoteHandler.param1.positionList || "").trim();
                        let tempArr = (positionList || '').split('\n') || [];
                        if (tempArr.length < 2) {
                            return;
                        }
                        // 第一个点数组
                        let firstPointArr = (tempArr[tempArr.length - 2] || '').split(',') || [];
                        if (firstPointArr && firstPointArr.length <= 3) {
                            this.remoteHandler.param1.x1 = firstPointArr[0];
                            this.remoteHandler.param1.y1 = firstPointArr[1];
                        }
                        // 第二个点数组
                        let secondPointArr = (tempArr[tempArr.length - 1] || '').split(',') || [];
                        if (secondPointArr && secondPointArr.length <= 3) {
                            this.remoteHandler.param1.x2 = secondPointArr[0];
                            this.remoteHandler.param1.y2 = secondPointArr[1];
                        }
                        // 生成图片
                        this.sendAction('param1', 'remoteClipGrayscaleAndThresholdToServer');
                        // 关闭快速裁图
                        this.remoteHandler.param1.isOpenFastClip = false;
                    }, 500)
                }
            },
            // 绘画鼠标移动
            drawMouseMove(e) {
                let box = document.querySelector('#previewImg');
                let xCoefficient = 1;
                let yCoefficient = 1;

                // x乘法系数
                let xMul = ((this.remoteHandler.param1.cache_x2 || 0) - (this.remoteHandler.param1.cache_x1 || 0)) / box.width;
                // y乘法系数
                let yMul = ((this.remoteHandler.param1.cache_y2 || 0) - (this.remoteHandler.param1.cache_y1 || 0)) / box.height;
                // 竖屏
                if (this.positionShowType === 'standard' && this.screenDirection === "竖屏") {
                    xCoefficient = xCoefficient * (this.deviceInfo.screenWidth || this.deviceInfo.standardWidth) / this.deviceInfo.standardWidth;
                    yCoefficient = yCoefficient * (this.deviceInfo.screenHeight || this.deviceInfo.standardHeight) / this.deviceInfo.standardHeight;
                    // 横屏
                } else if (this.positionShowType === 'standard' && this.screenDirection === "横屏") {
                    xCoefficient = xCoefficient * (this.deviceInfo.screenHeight || this.deviceInfo.standardHeight) / this.deviceInfo.standardHeight;
                    yCoefficient = yCoefficient * (this.deviceInfo.screenWidth || this.deviceInfo.standardWidth) / this.deviceInfo.standardWidth;
                }
                this.imgMousePosition.x = Number((e.offsetX * xMul) / xCoefficient).toFixed(0);
                this.imgMousePosition.y = Number((e.offsetY * yMul) / yCoefficient).toFixed(0);
                if (window.ctx) {
                    // 获取图片像素信息
                    let pixel = window.ctx.getImageData(this.imgMousePosition.x, this.imgMousePosition.y, 1, 1);
                    let data = pixel.data;
                    // 获取rgba值
                    let rgba = 'rgba(' + data[0] + ',' + data[1] + ',' + data[2] + ',' + (data[3] / 255) + ')';
                    // 设置小正方形的背景颜色
                    this.imgMousePosition.color = rgb2hex(rgba)
                }
                if (!this.remoteHandler.param1.isOpenFastClip) {
                    return;
                }
                if (!window.drawFlag) {
                    return;
                }
                let drawArear = document.getElementById('drawArear'); // 获取画布元素
                let drawReact = document.getElementById('drawReact'); // 获取矩形框元素
                let areaInfo = drawArear.getBoundingClientRect();

                // 鼠标移动的坐标 - 画布相对视窗的位置 - 矩形相对于画布的偏差（顶点位置） = 矩形框的大小
                window.reactWidth = e.clientX - areaInfo.x; // 宽
                window.reactHeight = e.clientY - areaInfo.y; // 高

                // 超出画布区域 宽度最大为 画布宽度
                window.reactWidth = e.clientX > areaInfo.right ? areaInfo.width + areaInfo.x - beginPoint.x : e.clientX - areaInfo.x;
                window.reactHeight = e.clientY > areaInfo.bottom ? areaInfo.height + areaInfo.y - beginPoint.y : e.clientY - areaInfo.y;

                let absoluteWidth = window.reactWidth - window.reactLeft; // 绝对宽度
                let absoluteHeight = window.reactHeight - window.reactTop; // 绝对高度

                drawReact.style.width = absoluteWidth + 'px'; // 宽
                drawReact.style.height = absoluteHeight + 'px'; // 高
            },
            // 生成代码
            generateCode(codeType) {
                if (!this.validSelectDevice()) {
                    return
                }
                // 清空代码
                this.remoteHandler.param1.scriptPreview = '';
                let code = '';
                // 灰度化
                if ('grayscale' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let afterImg = images.grayscale(img);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'images.save(afterImg, newFilepath);\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath)\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.recycleNull(afterImg);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    // 阈值化
                } else if ('threshold' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let afterImg = images.threshold(img,' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ');\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'images.save(afterImg, newFilepath);\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath)\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.recycleNull(afterImg);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    // 裁图
                } else if ('clip' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let afterImg = images.clip(img, ' + this.remoteHandler.param1.x1 + ', ' + this.remoteHandler.param1.y1 + ', ' + (this.remoteHandler.param1.x2 - this.remoteHandler.param1.x1) + ', ' + (this.remoteHandler.param1.y2 - this.remoteHandler.param1.y1) + ');\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'images.save(afterImg, newFilepath);\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath)\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.recycleNull(afterImg);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    // 找图
                } else if ('findImage' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let options = { threshold:' + this.remoteHandler.param1.imgThreshold + '};\r\n' +
                        'let result = images.findImage(img,targetImg,options);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 收集特征
                } else if ('detectAndComputeFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let options = { scale:' + this.remoteHandler.param1.bigScale + '};\r\n' +
                        'let result = images.detectAndComputeFeatures(img,options);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(result);\r\n' +
                        'utilsObj.recycleNull(result);';
                    // 特征匹配
                } else if ('matchFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let options1 = { scale:' + this.remoteHandler.param1.bigScale + '};\r\n' +
                        'let options2 = { scale:' + this.remoteHandler.param1.smallScale + '};\r\n' +
                        'let bigFeatures = images.detectAndComputeFeatures(img,options1);\r\n' +
                        'let smallFeatures = images.detectAndComputeFeatures(targetImg,options2);\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'let options3 = { drawMatches:newFilepath,thredshold:' + this.remoteHandler.param1.imgThreshold + '};\r\n' +
                        'let result = images.matchFeatures(bigFeatures,smallFeatures,options3);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'utilsObj.recycleNull(bigFeatures);\r\n' +
                        'utilsObj.recycleNull(smallFeatures);\r\n' +
                        'toastLog(JSON.stringify(result));\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath);\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    // 多点找色
                } else if ('findMultiColors' === codeType) {
                    // 获取多点转换参数
                    let multipleParam = this.multipleConvert();
                    code = 'let img = captureScreen();\r\n' +
                        'let options = {threshold:' + this.remoteHandler.param1.colorThreshold + '}\r\n' +
                        'let result = images.findMultiColors(img,' + multipleParam + ',options);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 谷歌MLKITOCR
                } else if ('MLKitOCR' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let MLKitOCR = $plugins.load("org.autojs.autojspro.plugin.mlkit.ocr");\r\n' +
                        'let googleOcr = new MLKitOCR();\r\n' +
                        'let resultMlk = googleOcr.detect(img);\r\n' +
                        'let contentMlkArr = Object.values(resultMlk).map(item => item.text) || [];\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(contentMlkArr));';
                    // 模板匹配
                } else if ('matchTemplate' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let matchingResult = images.matchTemplate(img,targetImg,{\r\n' +
                        '       threshold:' + this.remoteHandler.param1.imgThreshold + ',\r\n' +
                        '       max:5,\r\n' +
                        '       transparentMask:false,\r\n' +
                        '});\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(matchingResult));';
                    // 区域找图
                } else if ('regionalFindImg2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.regionalFindImg2(img,targetImg,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域找图测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域找图点击
                } else if ('regionalClickImg2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let tempImgPath = "' + this.remoteHandler.param1.previewImg + '";\r\n' +
                        'utilsObj.regionalClickImg2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',tempImgPath,' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',()=>{ toastLog("找到图片") });\r\n' +
                        'utilsObj.recycleNull(img);'
                    // 区域识字
                } else if ('regionalAnalysisChart2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.regionalAnalysisChart2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域识字测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域识字获取文字坐标
                } else if ('regionalAnalysisChartPosition2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.regionalAnalysisChartPosition2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',"目标文字",' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ');\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域模板匹配
                } else if ('regionalMatchTemplate2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.regionalMatchTemplate2(img,targetImg,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',5,false,' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域模板匹配测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域识字点击
                } else if ('regionalClickText2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'utilsObj.regionalClickText2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',"目标文字",' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',()=>{ toastLog("找到文字") });\r\n' +
                        'utilsObj.recycleNull(img);'
                    // 区域特征匹配点击
                } else if ('regionalClickFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let tempImgPath = "' + this.remoteHandler.param1.previewImg + '";\r\n' +
                        'utilsObj.regionalClickFeatures(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',tempImgPath,' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',()=>{ toastLog("找到特征") });\r\n' +
                        'utilsObj.recycleNull(img);'
                    // 区域特征匹配
                } else if ('regionalMatchingFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.regionalMatchingFeatures(img,targetImg,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域特征匹配测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域特征匹配模板
                } else if ('regionalMatchFeaturesTemplate' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.regionalMatchFeaturesTemplate(img,targetImg,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',5,"区域特征匹配测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域多点找色
                } else if ('regionalFindMultipleColor2' === codeType) {
                    // 获取多点转换参数
                    let multipleParam = this.multipleConvert();
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.regionalFindMultipleColor2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + multipleParam + ',' + this.remoteHandler.param1.colorThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域多点找色测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    //   区域多点找色点击
                } else if ('regionalClickColor2' === codeType) {
                    // 获取多点转换参数
                    let multipleParam = this.multipleConvert();
                    code = 'let img = captureScreen();\r\n' +
                        'utilsObj.regionalClickColor2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + multipleParam + ',' + this.remoteHandler.param1.colorThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',()=>{ toastLog("找到多点颜色") });\r\n' +
                        'utilsObj.recycleNull(img);'
                    // 区域找图或者特征匹配
                } else if ('regionalFindImgOrFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.regionalFindImgOrFeatures(img,targetImg,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域找图或者特征匹配测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域模板匹配或者特征匹配模板
                } else if ('regionalMatchTemplateOrMatchFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.regionalMatchTemplateOrMatchFeatures(img,targetImg,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',5,false,' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域模板匹配或者特征匹配模板测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 区域灰度化阈值化找圆
                } else if ('regionalFindCircles2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.regionalFindCircles2(img,' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"区域灰度化阈值化找圆测试代码");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 获取分辨率转换系数
                } else if ('getConvertCoefficient' === codeType) {
                    code = 'let result = utilsObj.getConvertCoefficient();\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 缩放小图
                } else if ('scaleSmallImg' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let smallImg = utilsObj.scaleSmallImg(img);\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'images.save(smallImg, newFilepath);\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath)\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.recycleNull(smallImg);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    // 按照分辨率转换坐标
                } else if ('convertXY' === codeType) {
                    code = 'let result = utilsObj.convertXY(' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',"");\r\n' +
                        'toastLog(JSON.stringify(result));';
                    // 图片特征匹配
                } else if ('detectFeaturesScale' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.detectFeaturesScale(img,targetImg,' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ');\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(result);\r\n';
                    // 灰度化阈值化特征匹配
                } else if ('matchingFeatures' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.matchingFeatures(img,targetImg,' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.bigScale + ',' + this.remoteHandler.param1.smallScale + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ',"");\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(result);\r\n';
                    // 随机点击
                } else if ('randomClick' === codeType) {
                    code = 'utilsObj.randomClick(' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',5,false);\r\n';
                    // 灰度化阈值化图片
                } else if ('grayscaleAndThreshold2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.grayscaleAndThreshold2(img,' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ');\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'images.save(result, newFilepath);\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath)\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.recycleNull(result);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    //灰度化阈值化找图
                } else if ('grayThresholdFindImg2' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let targetImg = images.load("' + this.remoteHandler.param1.previewImg + '");\r\n' +
                        'let result = utilsObj.grayThresholdFindImg2(img,targetImg,' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + this.remoteHandler.param1.imgThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ');\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.recycleNull(targetImg);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    //灰度化、阈值化多点找色
                } else if ('grayThresholdFindMultipleColor2' === codeType) {
                    // 获取多点转换参数
                    let multipleParam = this.multipleConvert();
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.grayThresholdFindMultipleColor2(img,' + this.remoteHandler.param1.threshold + ',' + this.remoteHandler.param1.maxVal + ',' + multipleParam + ',' + this.remoteHandler.param1.colorThreshold + ',' + this.remoteHandler.param1.isOpenGray + ',' + this.remoteHandler.param1.isOpenThreshold + ');\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    //ocr获取文字识别内容字符串结果
                } else if ('ocrGetContentStr' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.ocrGetContentStr(img);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'toastLog(JSON.stringify(result));';
                    //ocr获取文字识别内容字符串结果并绘图
                } else if ('ocrGetResultToCanvas' === codeType) {
                    code = 'let img = captureScreen();\r\n' +
                        'let result = utilsObj.ocrGetResultToCanvas(img);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'let newFilepath = "/sdcard/autoJsTools/imageHandlerAfter.png";\r\n' +
                        'files.createWithDirs("/sdcard/autoJsTools/");\r\n' +
                        'files.remove(newFilepath);\r\n' +
                        'images.save(result, newFilepath);\r\n' +
                        'toastLog("图片已存入本地:" + newFilepath)\r\n' +
                        'sleep(500);\r\n' +
                        'app.viewFile(newFilepath);\r\n' +
                        'utilsObj.recycleNull(result);\r\n' +
                        'utilsObj.recycleNull(img);\r\n' +
                        'utilsObj.textFindOneClick("仅此一次", 2000);';
                    // 绘制方框canvasRect
                } else if ('canvasRect' === codeType) {
                    code = 'utilsObj.canvasRect(' + this.remoteHandler.param1.x1 + ',' + this.remoteHandler.param1.y1 + ',' + this.remoteHandler.param1.x2 + ',' + this.remoteHandler.param1.y2 + ',"img","绘图");\r\n';
                }
                this.remoteHandler.param1.scriptPreview = code;
                window.ZXW_VUE.$notify.success({message: '生成代码成功', duration: '1000'})
            },
            // 执行预览代码
            execPreviewScript() {
                if (!this.validSelectDevice()) {
                    return
                }
                this.sendAction('param5', 'remoteExecScript', this.remoteHandler.param1.scriptPreview)
            },


            // 仅显示可见控件方法
            onlyShowVisible() {
                // 重置key数组
                this.remoteHandler.param5.nodeKeyArr = [];
                this.$refs.nodeTree.filter();
            },
            // 仅显示屏幕范围内控件
            onlyShowInScreen() {
                // 重置key数组
                this.remoteHandler.param5.nodeKeyArr = [];
                this.$refs.nodeTree.filter();
            },
            // 绘制背景图片
            showDrawBgImg() {
                // 获取已选中的节点
                let checkedNodes = this.$refs.nodeTree.getCheckedNodes();
                // 重新绘图
                this.rectNodeToCanvas(checkedNodes);
            },
            // 全选控件
            checkAllNode() {
                this.$refs.nodeTree.setCheckedKeys(this.remoteHandler.param5.checkAll ? this.remoteHandler.param5.nodeKeyArr : []);
                // 获取已选中的节点
                let checkedNodes = this.$refs.nodeTree.getCheckedNodes();
                // 重新绘图
                this.rectNodeToCanvas(checkedNodes);
            },
            // 控件过滤
            filterNode(value, data) {
                let nodeKeyArr = this.remoteHandler.param5.nodeKeyArr || [];
                let maxWidth = this.screenDirection === "竖屏" ? this.deviceInfo.screenWidth : this.deviceInfo.screenHeight;
                let maxHeight = this.screenDirection === "竖屏" ? this.deviceInfo.screenHeight : this.deviceInfo.screenWidth;
                let isOverScreen = false;
                let boundsInfo = data.boundsInfo;
                console.log(data.nodeKey);
                this.remoteHandler.param5.nodeKeyArr.push(data.nodeKey);
                if (boundsInfo) {
                    let x1 = boundsInfo.left;
                    let y1 = boundsInfo.top;
                    let x2 = boundsInfo.right;
                    let y2 = boundsInfo.bottom;
                    // 超出边界值范围 修改标志
                    if (x1 < 0 || x1 > maxWidth || y1 < 0 || y1 > maxHeight || x2 < 0 || x2 > maxWidth || y2 < 0 || y2 > maxHeight) {
                        isOverScreen = true;
                    }
                }
                // 两个条件同时满足
                if (this.remoteHandler.param5.isOnlyShowVisible && this.remoteHandler.param5.isOnlyShowInScreen) {
                    // 节点可见 且  没有超过范围的
                    /*if(data.visible && !isOverScreen && !nodeKeyArr.includes(data.nodeKey)){
                        nodeKeyArr.push(data.nodeKey);
                    }
                    this.remoteHandler.param5.nodeKeyArr = nodeKeyArr;*/
                    return data.visible && !isOverScreen;
                    // 可见节点过滤
                } else if (this.remoteHandler.param5.isOnlyShowVisible) {
                    /*if(data.visible && !nodeKeyArr.includes(data.nodeKey)){
                        nodeKeyArr.push(data.nodeKey);
                    }
                    this.remoteHandler.param5.nodeKeyArr = nodeKeyArr;*/
                    return data.visible;
                    // 屏幕范围内节点过滤
                } else if (this.remoteHandler.param5.isOnlyShowInScreen) {
                    // 没有超过范围的
                    /*if(!isOverScreen && !nodeKeyArr.includes(data.nodeKey)){
                        nodeKeyArr.push(data.nodeKey);
                    }
                    this.remoteHandler.param5.nodeKeyArr = nodeKeyArr;*/
                    return !isOverScreen;
                } else {
                    // 正常节点处理
                    /* if(!nodeKeyArr.includes(data.nodeKey)){
                         nodeKeyArr.push(data.nodeKey);
                     }
                     this.remoteHandler.param5.nodeKeyArr = nodeKeyArr;*/
                }
                return true;
            },
            // 远程布局分析
            remoteLayoutAnalysis() {
                if (!this.validSelectDevice()) {
                    return
                }
                // 发送指令并上传文件
                this.sendAction('param5', 'remoteExecScript', 'auto.clearCache();utilsObj.getRootNodeWriteLocal("tree");');
            },
            // 远程限制应用布局分析
            remoteLimitLayoutAnalysis() {
                // 发送指令
                this.sendAction('param5', 'remoteExecScript', 'utilsObj.remoteLimitLayoutAnalysis();');
            },
            // 上传并加载布局分析json
            uploadAndLoadNodeJson() {
                if (!this.validSelectDevice()) {
                    return
                }
                this.clearNodeJson();
                // 发送指令并上传文件
                this.sendAction('param5', 'remoteExecScript', 'utilsObj.remoteUploadRootNodeJsonToServer();utilsObj.uploadNodePreviewImg();');
                // 延时后读取json
                setTimeout(() => {
                    this.loadNodeJson();
                }, 1500)
            },
            // 执行预览代码
            execNodePreviewScript() {
                if (!this.validSelectDevice()) {
                    return
                }
                this.sendAction('param5', 'remoteExecScript', this.remoteHandler.param5.scriptPreview);
            },
            // 清空预览代码
            clearNodePreviewScript() {
                this.remoteHandler.param5.scriptPreview = "";
                window.ZXW_VUE.$notify.success({message: '操作成功', duration: '1000'})
            },
            // 节点右键点击
            nodeRightKeyFun(event, data, node, component) {
            },
            // 选中节点change
            currentChangeFun(data, node) {
            },
            // 节点信息点击
            nodeContentClick(e) {
                this.remoteHandler.param5.nodeInfo = e.target.innerHTML;
            },
            // 节点左键点击
            nodeClickFun(data, node, component) {
                // 获取已选中的节点
                let checkedNodes = this.$refs.nodeTree.getCheckedNodes();
                // 重新绘图
                this.rectNodeToCanvas(checkedNodes);
                // 高亮画框
                let boundsInfo = data.boundsInfo;
                let x1 = boundsInfo.left;
                let y1 = boundsInfo.top;
                let x2 = boundsInfo.right;
                let y2 = boundsInfo.bottom;
                let width = Number(x2) - Number(x1);
                let height = Number(y2) - Number(y1);
                window.ctxNode.beginPath();
                // 设置颜色 高亮色
                window.ctxNode.strokeStyle = "#c4d10c";
                //绘制一个方框
                window.ctxNode.strokeRect(Number(x1), Number(y1), width, height);
                window.ctxNode.closePath();

                this.remoteHandler.param5.selectNode = data;
                this.remoteHandler.param5.dialogVisible = true;

                // 点击生成代码
                this.nodeGenerateCode();
            },
            // 节点选中
            nodeCheckFun(data, treeNode) {
                if (!window.nodeSourceImg) {
                    return;
                }
                this.rectNodeToCanvas(treeNode.checkedNodes);
            },
            // 画框到canvas
            rectNodeToCanvas(checkedNodes) {
                // 清空画框数组
                this.remoteHandler.param5.rectCanvasArr = [];
                // 获取canvas对象
                let canvas = document.getElementById('nodePreviewCanvas');
                window.ctxNode.beginPath();
                // 先清除画布
                window.ctxNode.clearRect(0, 0, canvas.width, canvas.height); //清空这个范围的画布

                if (this.remoteHandler.param5.isShowBgImg) {
                    // 重新画图
                    window.ctxNode.drawImage(window.nodeSourceImg, 0, 0, canvas.width, canvas.height);
                }
                window.ctxNode.strokeStyle = "#9a3616";
                window.ctxNode.lineWidth = 3;
                // 获取全部已选择节点
                let checkNodes = checkedNodes;
                // 按照层级倒序
                checkNodes = sortByKey(checkNodes, 'depth', false);
                if (window.ctxNode && checkNodes && checkNodes.length) {
                    for (let i = 0; i < checkNodes.length; i++) {
                        let checkNode = checkNodes[i];
                        let boundsInfo = checkNode.boundsInfo;
                        let x1 = boundsInfo.left;
                        let y1 = boundsInfo.top;
                        let x2 = boundsInfo.right;
                        let y2 = boundsInfo.bottom;
                        let width = Number(x2) - Number(x1);
                        let height = Number(y2) - Number(y1);
                        //绘制一个方框
                        window.ctxNode.rect(Number(x1), Number(y1), width, height);
                        // 添加方框数组
                        this.remoteHandler.param5.rectCanvasArr.push({
                            nodeKey: checkNode.nodeKey,
                            index: i,
                            x1: x1,
                            y1: y1,
                            x2: x2,
                            y2: y2,
                            width: width,
                            height: height
                        })
                    }
                }
                window.ctxNode.stroke();
                window.ctxNode.closePath();
            },
            // 加载节点Json
            loadNodeJson() {
                let _that = this;
                // 设置key数组
                _that.remoteHandler.param5.nodeKeyArr = [];
                $.ajax({
                    url: "/uploadPath/autoJsTools/" + this.deviceInfo.deviceUuid + "/rootNode.json",
                    type: "GET",//请求方式为get
                    dataType: "json", //返回数据格式为json
                    success: function (data) {//请求成功完成后要执行的方法
                        _that.remoteHandler.param5.rootNodeJson = JSON.stringify(data, "", "\t");
                        // 赋值对象
                        _that.remoteHandler.param5.rootNodeObj = [data];
                        // 删除节点信息显示
                        _that.remoteHandler.param5.dialogVisible = false;
                        // 加载控件图片
                        let imgUrl = getContext() + "/uploadPath/autoJsTools/" + _that.deviceInfo.deviceUuid + "/nodePreviewImg.jpg";
                        _that.$nextTick(() => {
                            _that.$refs.nodeTree.filter();
                            $("#nodePreviewImg").attr("src", imgUrl + "?t=" + new Date().getTime());
                            let img = new Image();
                            img.src = imgUrl + "?t=" + new Date().getTime();
                            let canvas = document.getElementById('nodePreviewCanvas');
                            canvas.width = _that.screenDirection === "竖屏" ? _that.deviceInfo.screenWidth : _that.deviceInfo.screenHeight;
                            canvas.height = _that.screenDirection === "竖屏" ? _that.deviceInfo.screenHeight : _that.deviceInfo.screenWidth;
                            window.ctxNode = canvas.getContext('2d');
                            // 储存原始图像
                            window.nodeSourceImg = img;
                            img.onload = function () {
                                if (_that.remoteHandler.param5.isShowBgImg) {
                                    // 在canvas上画图片
                                    window.ctxNode.drawImage(img, 0, 0, canvas.width, canvas.height);
                                }
                            };

                            canvas.removeEventListener('click', _that.nodeMouseClick);
                            canvas.addEventListener('click', _that.nodeMouseClick);

                            canvas.removeEventListener('contextmenu', _that.nodeMouseRightClick);
                            canvas.addEventListener('contextmenu', _that.nodeMouseRightClick);


                            canvas.removeEventListener('mousemove', _that.nodeMouseMove);
                            canvas.addEventListener('mousemove', _that.nodeMouseMove);

                            setTimeout(() => {
                                // 获取已选中的节点
                                let checkedNodes = _that.$refs.nodeTree.getCheckedNodes();
                                // 重新绘图
                                _that.rectNodeToCanvas(checkedNodes);
                            }, 500)
                        });
                        if (data && data.msg) {
                            window.ZXW_VUE.$notify.error({message: data.msg, duration: '2000'})
                        } else {
                            window.ZXW_VUE.$notify.success({message: '加载完成', duration: '1000'})
                        }
                    },
                    error: function (msg) {
                    }
                })
            },
            // 清除节点Json
            clearNodeJson(showMessage) {
                this.remoteHandler.param5.rootNodeJson = "";
                // 赋值对象
                this.remoteHandler.param5.rootNodeObj = [];
                window.nodeSourceImg = null;
                // 获取canvas对象
                let canvas = document.getElementById('nodePreviewCanvas');
                if (window.ctxNode && canvas && canvas.width) {
                    window.ctxNode.beginPath();
                    // 先清除画布
                    window.ctxNode.clearRect(0, 0, canvas.width, canvas.height); //清空这个范围的画布
                    window.ctxNode.closePath();
                }
                // 删除节点信息显示
                this.remoteHandler.param5.dialogVisible = false;
                // 清空控件框数组
                this.remoteHandler.param5.rectCanvasArr = [];
                // 取消全选
                this.remoteHandler.param5.checkAll = false;
                if (showMessage) {
                    window.ZXW_VUE.$notify.success({message: '清空完成', duration: '1000'})
                }
            },
            // 控件鼠标移动监听
            nodeMouseMove(e) {
                let canvas = document.getElementById('nodePreviewCanvas');
                let x = e.offsetX * (canvas.width / canvas.offsetWidth);
                let y = e.offsetY * (canvas.height / canvas.offsetHeight);
                let rectCanvasArr = JSON.parse(JSON.stringify(this.remoteHandler.param5.rectCanvasArr || []));
                // 倒序数组
                // rectCanvasArr = rectCanvasArr.reverse();
                // 重绘数组
                let reRectCanvasArr = [];
                // 第一个所在范围的方框
                let inRect = null;
                // 遍历  从小范围到大范围
                for (let i = 0; i < rectCanvasArr.length; i++) {
                    let rect = rectCanvasArr[i];
                    // 在范围内
                    let inRectRange = (x >= rect.x1 && y >= rect.y1 && x <= rect.x2 && y <= rect.y2);
                    // 如果在范围内
                    if (inRectRange) {
                        // 还没有第一个符合的方框
                        if (!inRect) {
                            // 设置第一个方框
                            inRect = rect;
                            continue;
                        }
                    }
                    // 添加到重绘元素中
                    reRectCanvasArr.push(rect);
                }
                window.ctxNode.beginPath();
                window.ctxNode.lineWidth = 3;
                // 方框颜色 原始色
                let rectColor = "#9a3616";
                for (let i = 0; i < reRectCanvasArr.length - 1; i++) {
                    let reRect = reRectCanvasArr[i];
                    // 原始色
                    rectColor = "#9a3616";
                    // 设置颜色
                    window.ctxNode.strokeStyle = rectColor;
                    // 画框
                    window.ctxNode.rect(reRect.x1, reRect.y1, reRect.width, reRect.height);
                }
                window.ctxNode.stroke();
                if (inRect) {
                    // 高亮色
                    rectColor = "#c4d10c";
                    // 设置颜色
                    window.ctxNode.strokeStyle = rectColor;
                    // 画框
                    window.ctxNode.strokeRect(inRect.x1, inRect.y1, inRect.width, inRect.height);
                }
                this.remoteHandler.param5.highlightRect = inRect;
                window.ctxNode.closePath();
            },
            // 监控鼠标右键
            nodeMouseRightClick(e) {
                e.stopPropagation();
                e.preventDefault();
                let canvas = document.getElementById('nodePreviewCanvas');
                let x = e.offsetX * (canvas.width / canvas.offsetWidth);
                let y = e.offsetY * (canvas.height / canvas.offsetHeight);
                let rectCanvasArr = JSON.parse(JSON.stringify(this.remoteHandler.param5.rectCanvasArr || []));
                // 第一个所在范围的方框
                let inRect = null;
                // 遍历  从小范围到大范围
                for (let i = 0; i < rectCanvasArr.length; i++) {
                    let rect = rectCanvasArr[i];
                    // 在范围内
                    let inRectRange = (x >= rect.x1 && y >= rect.y1 && x <= rect.x2 && y <= rect.y2);
                    // 如果在范围内
                    if (inRectRange) {
                        // 还没有第一个符合的方框
                        if (!inRect) {
                            // 设置第一个方框
                            inRect = rect;
                        }
                    }
                }
                if (inRect) {
                    // 取消勾选
                    this.$refs.nodeTree.setChecked(inRect.nodeKey, false, false)
                }
                this.remoteHandler.param5.highlightRect = null;
                // 获取已选中的节点
                let checkedNodes = this.$refs.nodeTree.getCheckedNodes();
                // 重新绘图
                this.rectNodeToCanvas(checkedNodes);
            },
            // 控件鼠标点击监听
            nodeMouseClick(e) {
                let highlightRect = this.remoteHandler.param5.highlightRect;
                // 当前已有高亮方框
                if (highlightRect) {
                    let nodeObj = this.$refs.nodeTree.getNode(highlightRect.nodeKey);
                    this.remoteHandler.param5.selectNode = nodeObj.data;
                    this.remoteHandler.param5.dialogVisible = true;
                    // 点击生成代码
                    this.nodeGenerateCode();
                }
            },
            // 控件节点生成代码
            nodeGenerateCode() {
                // 未开启不生成
                if (!this.remoteHandler.param5.openClickGenerateCode) {
                    return;
                }
                // 获取选中节点
                let selectNode = this.remoteHandler.param5.selectNode;
                if (!selectNode) {
                    return;
                }
                let id = selectNode.id;
                let text = selectNode.text;
                let desc = selectNode.desc;
                let className = selectNode.className;

                let uiSelect = this.remoteHandler.param5.uiSelect;
                let uiSelectCondition = this.remoteHandler.param5.uiSelectCondition;
                let uiSelectAction = this.remoteHandler.param5.uiSelectAction;

                let nodeCode = '';
                if (uiSelect.includes("id") && id) {
                    nodeCode += 'id("' + id + '")';
                }
                if (uiSelect.includes("text") && text) {
                    if (nodeCode) {
                        nodeCode += '.';
                    }
                    nodeCode += 'text("' + text + '")';
                }
                if (uiSelect.includes("desc") && desc) {
                    if (nodeCode) {
                        nodeCode += '.';
                    }
                    nodeCode += 'desc("' + desc + '")';
                }
                if (uiSelect.includes("className") && className) {
                    if (nodeCode) {
                        nodeCode += '.';
                    }
                    nodeCode += 'className("' + className + '")';
                }
                if (uiSelectCondition) {
                    nodeCode += '.' + uiSelectCondition + '()';
                }
                if (uiSelectAction) {
                    nodeCode += '.' + uiSelectAction + '()';
                }
                this.remoteHandler.param5.scriptPreview += nodeCode + "\r\n";
            },


            // 开始预览设备
            startPreviewDevice(notice) {
                let messageStr = JSON.stringify(this.devicePreviewParam);
                this.sendMsgToClient('startPreviewDevice', messageStr, () => {
                    this.deviceInfo.startPreview = true;
                    if (notice) {
                        window.ZXW_VUE.$notify.success({
                            message: '开始预览',
                            duration: '500'
                        })
                    }
                    if (window.refreshDeviceInterval) {
                        clearInterval(window.refreshDeviceInterval)
                    }
                    $("#devicePreviewImg").css("height", this.devicePreviewParam.previewHeight + "px");
                    window.refreshDeviceInterval = setInterval(() => {
                        window.deviceImgUrl = getContext() + "/uploadPath/autoJsTools/" + this.deviceInfo.deviceUuid + "/tempImg.jpg" + "?t=" + new Date().getTime();
                        $("#devicePreviewImg").attr("src", window.deviceImgUrl);
                        window.deviceImgUrlBak = window.deviceImgUrl
                    }, this.devicePreviewParam.clientSpace);


                    let devicePreviewBox = document.querySelector('#devicePreviewImg');
                    devicePreviewBox.removeEventListener('mousemove', this.deviceMouseMove);
                    devicePreviewBox.addEventListener('mousemove', this.deviceMouseMove);

                    devicePreviewBox.removeEventListener('click', this.deviceMouseClick);
                    devicePreviewBox.addEventListener('click', this.deviceMouseClick);

                    devicePreviewBox.removeEventListener('mousedown', this.deviceMouseDown);
                    devicePreviewBox.addEventListener('mousedown', this.deviceMouseDown, true);

                    devicePreviewBox.removeEventListener('mouseup', this.deviceMouseUp);
                    devicePreviewBox.addEventListener('mouseup', this.deviceMouseUp, true);
                })
            },
            // 停止预览设备
            stopPreviewDevice(notice, callback) {
                this.sendMsgToClient('stopPreviewDevice', '', () => {
                    this.deviceInfo.startPreview = false;
                    if (notice) {
                        window.ZXW_VUE.$notify.success({
                            message: '停止预览',
                            duration: '500'
                        })
                    }
                    if (window.refreshDeviceInterval) {
                        clearInterval(window.refreshDeviceInterval)
                    }
                    if (callback) {
                        callback()
                    }
                })
            },
            // 自动预览设备
            autoDevicePreview() {
                if (!this.devicePreviewParam.valueUpdateAfterAutoPreview) {
                    return
                }
                this.stopPreviewDevice(false, () => {
                    this.startPreviewDevice(false)
                })
            },
            // 固定操作
            fixedOperate(operateName) {
                if (!this.deviceInfo.startPreview) {
                    return
                }
                let operateCode = operateName + '()';
                this.devicePreviewParam.operateRecord += operateCode + ";";
                this.sendAction('param5', 'remoteExecScript', operateCode);
            },
            // 设备鼠标点击
            deviceMouseClick() {
                if (!this.deviceInfo.startPreview) {
                    return
                }
                let resetPosition = function () {
                    // 重置位置
                    window.deviceMouseX1 = 0;
                    window.deviceMouseY1 = 0;
                    window.deviceMouseStartTime = 0;
                    window.deviceMouseX2 = 0;
                    window.deviceMouseY2 = 0;
                    window.deviceMouseEndTime = 0;
                };
                let positionVal1 = window.deviceMouseX1 + "," + window.deviceMouseY1;
                let positionVal2 = window.deviceMouseX2 + "," + window.deviceMouseY2;
                // 坐标不相同
                if (positionVal1 !== positionVal2) {
                    resetPosition();
                    return;
                }
                let operateCode = 'click(' + this.deviceMousePosition.x + ',' + this.deviceMousePosition.y + ')';
                this.sendAction('param5', 'remoteExecScript', operateCode);
                this.devicePreviewParam.operateRecord += operateCode + ";";
            },
            // 设备鼠标按下
            deviceMouseDown(e) {
                // 按下记录开始鼠标位置
                window.deviceMouseX1 = this.deviceMousePosition.x;
                window.deviceMouseY1 = this.deviceMousePosition.y;
                window.deviceMouseStartTime = new Date().getTime();
            },
            // 设备鼠标移动
            deviceMouseMove(e) {
                let box = document.querySelector('#devicePreviewImg');
                // 竖屏
                if (this.screenDirection === "竖屏") {
                    this.deviceMousePosition.x = Number(e.offsetX * (this.deviceInfo.screenWidth / box.width)).toFixed(0);
                    this.deviceMousePosition.y = Number(e.offsetY * (this.deviceInfo.screenHeight / box.height)).toFixed(0);
                    // 横屏
                } else if (this.screenDirection === "横屏") {
                    this.deviceMousePosition.x = Number(e.offsetX * (this.deviceInfo.screenHeight / box.width)).toFixed(0);
                    this.deviceMousePosition.y = Number(e.offsetY * (this.deviceInfo.screenWidth / box.height)).toFixed(0);
                }
            },
            // 设备鼠标松开
            deviceMouseUp(e) {
                // 松开记录结束鼠标位置
                window.deviceMouseX2 = this.deviceMousePosition.x;
                window.deviceMouseY2 = this.deviceMousePosition.y;
                window.deviceMouseEndTime = new Date().getTime();

                let positionVal1 = window.deviceMouseX1 + "," + window.deviceMouseY1;
                let positionVal2 = window.deviceMouseX2 + "," + window.deviceMouseY2;
                // 坐标值不相同
                if (positionVal1 !== positionVal2) {
                    if (!this.deviceInfo.startPreview) {
                        return
                    }
                    let operateCode = 'swipe(' + window.deviceMouseX1 + ',' + window.deviceMouseY1 + ',' + window.deviceMouseX2 + ',' + window.deviceMouseY2 + ',' + (window.deviceMouseEndTime - window.deviceMouseStartTime) + ')';
                    this.devicePreviewParam.operateRecord += operateCode + ";";
                    // 发送滑动指令
                    this.sendAction('param5', 'remoteExecScript', operateCode);
                    // 坐标相同
                } else {
                    // 大于500毫秒 即为长按
                    if (window.deviceMouseEndTime - window.deviceMouseStartTime > 500) {
                        if (!this.deviceInfo.startPreview) {
                            return
                        }
                        let operateCode = 'longClick(' + window.deviceMouseX1 + ',' + window.deviceMouseY1 + ')';
                        this.devicePreviewParam.operateRecord += operateCode + ";";
                        // 发送长按指令
                        this.sendAction('param5', 'remoteExecScript', operateCode);
                    }
                }
            },


            // 远程运行脚本
            remoteRunScript() {

            },


            // 加载日志
            loadPreviewLog() {
                if (!this.validSelectDevice()) {
                    return
                }
                this.remoteHandler.param2.previewLog = "";
                let logUrl = getContext() + "/uploadPath/autoJsTools/" + this.deviceInfo.deviceUuid + "/" + this.remoteHandler.param2.logName;
                setTimeout(() => {
                    this.remoteHandler.param2.previewLog = logUrl;
                    this.$nextTick(() => {
                        $("#previewLog").attr("src", logUrl + "?t=" + new Date().getTime());
                    });
                }, 200);
            },
            // 下载日志
            downLoadLog() {
                if (!this.validSelectDevice()) {
                    return
                }
                if (this.remoteHandler.param2.previewLog) {
                    window.open(this.remoteHandler.param2.previewLog)
                }
            },
        }
    })
</script>
</body>
</html>